#pragma once

#include <boost/asio.hpp>
#include <tbb/atomic.h>

#include "Reply.h"
#include "Request.h"
#include "RequestParser.h"


// Forward declaration
class WorkManager;


/// Represents a single connection from a client
class TcpConnection
{
public:
	/// Construct a connection with the given io_service
	TcpConnection(boost::asio::io_service &ioService, WorkManager &manager);

	/// Allocates memory for this class using scalable_allocator
	void *operator new(size_t blockSize);

	/// Deallocates memory of this class using scalable_allocator
	void operator delete(void *pointer);

	/// Returns underlying socket
	boost::asio::ip::tcp::socket &getSocket() { return _socket; }

	/// Starts the first asynchronous operation for the connection
	void StartParsing();

//internal
	/// Asynchronously parses results of read operation
	void ParseReadAsync();

	/// Asynchronously parses results of write operation
	void ParseWriteAsync();

private:
	enum AsyncOperation
	{
		None,
		Read,
		Write,
	};

	/// Handles completion of a read operation
	void HandleRead(const boost::system::error_code &e, size_t bytes_transferred);

	/// Handles completion of a write operation
	void HandleWrite(const boost::system::error_code &e);

	/// Expected Asynchronous operation
	AsyncOperation _asyncOperationExpected;

	/// Buffer for incoming data
	boost::array<char, 8192> _buffer;

	/// Meaningful size of the buffer
	size_t _bufferSize;

	/// Work manager
	WorkManager &_manager;

	/// The reply to be sent back to the client
	Reply _reply;

	/// The incoming request
	Request _request;

	/// The parser for the incoming request
	RequestParser _requestParser;

	/// Socket for the connection
	boost::asio::ip::tcp::socket _socket;
};
